#include "ntddk.h"

char buf[3000];

NTSTATUS driverInit  (IN PDEVICE_OBJECT dev, IN PIRP irp);
NTSTATUS driverControl (IN PDEVICE_OBJECT dev, IN PIRP irp);
VOID     driverUnload  (IN PDRIVER_OBJECT dev);
NTSTATUS write(IN PDEVICE_OBJECT dev, IN PIRP irp);
NTSTATUS read(IN PDEVICE_OBJECT dev, IN PIRP irp);

NTSTATUS complete(int size, IN PIRP irp)
{        
        irp->IoStatus.Status      = STATUS_SUCCESS;
        irp->IoStatus.Information = size;
        IoCompleteRequest(irp, IO_NO_INCREMENT);
                 
        return STATUS_SUCCESS;
}
 
NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject,IN PUNICODE_STRING RegistryPath)
{
        NTSTATUS       status;
        PDEVICE_OBJECT dev;
        UNICODE_STRING name;
        UNICODE_STRING link;
  
        driverObject->DriverUnload                         = driverUnload;
        driverObject->MajorFunction[IRP_MJ_CREATE]         = driverInit;
        driverObject->MajorFunction[IRP_MJ_CLOSE]          = driverInit;
        driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = driverInit;
        driverObject->MajorFunction[IRP_MJ_READ] = read;
        driverObject->MajorFunction[IRP_MJ_WRITE] = write;
  
        RtlInitUnicodeString(&name,L"\\Device\\driver");
  
        status = IoCreateDevice(driverObject,sizeof(PDEVICE_OBJECT),&name,FILE_DEVICE_UNKNOWN,0,FALSE,&dev);
        dev->Flags |= DO_BUFFERED_IO;
        if(!NT_SUCCESS(status))return status;
        RtlInitUnicodeString(&link,L"\\??\\driver");
  
        return IoCreateSymbolicLink(&link,&name);
}
  
NTSTATUS driverInit(IN PDEVICE_OBJECT dev, IN PIRP irp)
{
        return complete(0, irp);
}
  
VOID driverUnload(IN PDRIVER_OBJECT dev)
{
        UNICODE_STRING deviceLink;
        RtlInitUnicodeString(&deviceLink,L"\\??\\driver");
        IoDeleteSymbolicLink(&deviceLink);
        IoDeleteDevice(dev->DeviceObject);
}

NTSTATUS write(IN PDEVICE_OBJECT fdo, IN PIRP irp)
{
        void* buffer = NULL;
        long size = 0;
  
        PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(irp);
  
        size  = stack->Parameters.Write.Length;
        buffer = irp->AssociatedIrp.SystemBuffer;
        memcpy(buf + strlen(buf), buffer, size);
         
         
#if DBG
        DbgPrint("Buffer: %s",buf);
#endif
  
        return complete(size, irp);
}
NTSTATUS read(IN PDEVICE_OBJECT fdo, IN PIRP irp)
{
        void* buffer = NULL;
        long size = 0;
  
        PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(irp);
  
        size  = stack->Parameters.Read.Length;
        buffer = irp->AssociatedIrp.SystemBuffer;
  
        RtlCopyMemory(buffer,&buf,size);
#if DBG
        DbgPrint("Buffer: %s",buf);
#endif
                 
        return complete(size, irp);
}
